const EventEmitter = require('events');

/**
 * 带中间件功能的事件发射器
 * 继承自 Node.js 内置的 EventEmitter
 */
class MiddlewareEventEmitter extends EventEmitter {
  constructor() {
    super();
    // 存储每个事件的中间件
    this.middlewares = new Map();
  }

  /**
   * 注册事件中间件
   * @param {string|RegExp} eventName - 事件名称或正则表达式
   * @param {Function} middleware - 中间件函数，格式为 (...args, next) => {}
   * @returns {MiddlewareEventEmitter} 返回实例本身，支持链式调用
   */
  use(eventName, middleware) {
    if (typeof middleware !== 'function') {
      throw new TypeError('Middleware must be a function');
    }

    // 为正则表达式创建一个唯一标识符
    const key = eventName instanceof RegExp ? `regexp:${eventName.source}:${eventName.flags}` : eventName;

    if (!this.middlewares.has(key)) {
      this.middlewares.set(key, []);
      // 如果是正则表达式，存储其原始对象
      if (eventName instanceof RegExp) {
        this.middlewares.set(`regexpObj:${key}`, eventName);
      }
    }
    this.middlewares.get(key).push(middleware);
    return this;
  }

  /**
   * 触发事件，并在触发前执行中间件
   * @param {string} eventName - 事件名称
   * @param {...*} args - 传递给事件监听器的参数
   * @returns {boolean} 是否有监听器被调用
   */
  emit(eventName, ...args) {
    // 1. 获取完全匹配的事件中间件
    const exactMiddlewares = this.middlewares.get(eventName) || [];

    // 2. 获取匹配的正则表达式中间件
    const regexMiddlewares = [];
    for (const key of this.middlewares.keys()) {
      if (key.startsWith('regexp:')) {
        const regexObj = this.middlewares.get(`regexpObj:${key}`);
        if (regexObj.test(eventName)) {
          regexMiddlewares.push(...this.middlewares.get(key));
        }
      }
    }

    // 合并所有中间件
    const middlewares = [...exactMiddlewares, ...regexMiddlewares];

    // 如果没有中间件，直接触发事件
    if (middlewares.length === 0) {
      return super.emit(eventName, ...args);
    }

    // 创建一个可修改的参数副本
    let modifiedArgs = [...args];
    let hasError = false;

    // 执行中间件链
    const runMiddlewares = (index) => {
      if (index >= middlewares.length || hasError) {
        // 所有中间件执行完毕或发生错误，触发原始事件
        if (!hasError) {
          return super.emit(eventName, ...modifiedArgs);
        }
        return false;
      }

      try {
        // 执行当前中间件
        middlewares[index](...modifiedArgs, (err, ...newArgs) => {
          if (err) {
            // 处理中间件错误
            hasError = true;
            console.error(`Middleware error for event \${eventName}:`, err);
            // 触发错误事件
            this.emit('error', err);
            return;
          }

          // 更新参数
          if (newArgs.length > 0) {
            modifiedArgs = newArgs;
          }

          // 执行下一个中间件
          runMiddlewares(index + 1);
        });
      } catch (err) {
        hasError = true;
        console.error(`middleware exception for event \${eventName}:`, err);
        this.emit('error', err);
      }
    };

    runMiddlewares(0);
    return true;
  }
}

// 导出模块
module.exports = MiddlewareEventEmitter;